\chapter{Objects}
\label{cha:objects}

    For high level components, an object oriented approach was taken to
    allow for a greater flexibility through the inheritance and polymorphism
    concepts. This appendix gives some details on the usage and implementation
    of objects for advanced users.

\section{Declaration, construction and destruction}
\label{sec:declaration}

  All object types are of the form it\_objectname\_t. All objects are
  deleted using the expression \function{it\_delete(x)} where $x$ is an object.

\begin{program}{Object}{pro:object}
/* declare a scalar quantizer object */
it_scalar_quantizer_t *scalar_quantizer; 

/* create and initialize a new scalar quantizer centered on 0 with step 1 */
scalar_quantizer = it_scalar_quantizer_new_from_center(0, 1);

/* delete the scalar_quantizer object */
it_delete(scalar_quantizer, v);
\end{program}


\section{Casting}
\label{sec:casting}

     Casting is done using macros of the form 'IT\_OBJECTNAME(x)',
     which cast the object 'x' to the type 'it\_objectname\_t'. If the
     object cannot be cast properly to one of its parent types, an
     error will be displayed at runtime.

\begin{program}{Casting}{pro:casting}
/* declare a quantizer object */
it_quantizer_t *quantizer; 

/* cast the object 'scalar_quantizer' to its parent type 'it_quantizer_t' */
quantizer = IT_QUANTIZER(scalar_quantizer);
\end{program}


\section{Polymorphism}
\label{sec:polymorphism}

  Polymorphism allows to use an object in a place where a parent
  object is expected. The child object is seen as the parent object
  except the methods of the child class are called, rather than the
  methods of the parent class.  

\begin{program}{Polymorphism}{pro:polymorphism}
it_scalar_quantizer_t *scalar_quantizer; /* declare a scalar quantizer object */
it_quantizer_t *quantizer; /* declare a quantizer object */
vec v = vec_new_ones(10);  /* a vector */

/* create and initialize a new scalar quantizer centered on 0 with step 1 */
scalar_quantizer = it_scalar_quantizer_new_from_center(0, 1);

/* cast the it_scalar_quantizer_t object to a it_quantizer_t object. */
/* valid since it_quantizer_t is the parent of it_scalar_quantizer_t */
quantizer = IT_QUANTIZER(scalar_quantizer);

/* call a method of the it_quantizer_t class on the quantizer. */
/* the method called is that of it_scalar_quantizer_t due to polymorphism. */
it_quantize(quantizer, v);

/* this does the same thing as above, with a simpler syntax. */
it_quantize(scalar_quantizer, v);
\end{program}

\section{Comments on implementation}
\label{sec:comments}

     The object orientated mechanisms in libit are greatly inspired
  from Glib/GTK \url{http://www.gtk.org/}. Objects are
  implemented as structures. Methods are implemented as functions
  pointers inside the object structure. Inheritance is achieved by
  placing the expression 'it\_extends(it\_parent\_t)' where it\_parent\_t
  is the type of the parent object. All objects inherit from the type
  'it\_object\_t'. Dynamic type checking is achieved by assigning a
  unique identifier (UID) to each object type and keeping track of the
  inheritance structure. 
